﻿using System;
using System.Net;
using System.Threading;

using UdpTransceiver;
using ParametersParser;
using Communicator;

namespace ApplicationSlave
{
    /// <summary>
    /// Тестовое приложение использования коммуникатора в режиме ведомого узла
    /// Для тестирования установите этот проект в качестве запускающего 
    /// и поменяйте настройки приложения на Slave
    /// </summary>
    class Program
    {
        /// <summary>
        /// Признак активного полета
        /// </summary>
        static bool Flight = true;

        static Communicator.Communicator Communicator;

        /// <summary>
        /// Обработчик события отсылки непустого пакета
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void SentPackageHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие отправки пакета
            Console.WriteLine("\nОтправлен пакет данных");
        }

        /// <summary>
        /// Обработчик события приема непустого пакета
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void ReceivedPackageHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие приема пакета
            Console.WriteLine("\nПринят пакет данных");
        }

        static public void InputParametersChangedHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие изменения входных параметров
            Console.WriteLine("\nИзменились входные параметры");
        }

        /// <summary>
        /// Обработчик события обмена коммуникатора (приема или отсылки любого инфо-пакета)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="a"></param>
        static public void ExchangeHandler(object sender, EventArgs a)
        {
            Console.Clear();
            Console.WriteLine("\nПроизошел какой-то обмен пакетами");
        }

        static public void CommunicatorTickHandler(object sender, EventArgs a)
        {
            // Здесь обратывается событие окончания цикла коммуникатора
            Console.WriteLine("\nЗакончен цикл коммуникатора");
            Console.WriteLine("{0}\n Input parameters:", DateTime.Now);
            foreach (Parameter Item in Communicator.Parameters)
                if (Item.Direction == ParameterDirection.input || Item.Direction == ParameterDirection.inpout)
                    Console.Write("{0} = {1};\t", Item.Name, Item.Value);
            Console.WriteLine("\nOutput parameters");
            foreach (Parameter Item in Communicator.Parameters)
                if (Item.Direction == ParameterDirection.output || Item.Direction == ParameterDirection.inpout)
                    Console.Write("{0} = {1};\t", Item.Name, Item.Value);
        }

        static void Main(string[] args)
        {
            Thread.GetDomain().UnhandledException += new UnhandledExceptionEventHandler(Program_UnhandledException);

            // Создаем экземпляр коммуникатора
            Communicator = new Communicator.Communicator();

            Console.WriteLine("Start exchange? (y/n)");
            if (Console.ReadLine() == "y")
            {
                Console.WriteLine("Initializing communicator...( Q - exit )");

                // Подписываемся на события коммуникатора
                Communicator.DataSent += SentPackageHandler;
                Communicator.DataReceived += ReceivedPackageHandler;
                Communicator.DataExchange += ExchangeHandler;
                Communicator.InputParameterChanged += InputParametersChangedHandler;
                Communicator.ExchangeTick += CommunicatorTickHandler;

                // Запускаем коммуникатор для обмена
                Communicator.Start();

                // Подписываемся на отправку и получение параметров
                // Исходящие
                Communicator.AddParameter("ALT", ParameterDirection.input);
                Communicator.AddParameter("AIRSPEED", ParameterDirection.input);
                // Входящие
                Communicator.AddParameter("STOP_FLIGHT", ParameterDirection.output);

                int i = 0;
                // Летим
                while (Flight)
                {
                    i++;
                    if (Convert.ToUInt16(Communicator.GetParameterValueByName("ALT")) > 500)
                        Communicator.SetParameterValueByName("STOP_FLIGHT", "1");


                    // Типа занимаемся чем-то еще
                    Thread.Sleep(500);
                    ConsoleKeyInfo cki = new ConsoleKeyInfo();

                    // Выход по нажатию клавиши Ку
                    if (Console.KeyAvailable == true)
                    {
                        cki = Console.ReadKey(true);
                        if (cki.Key == ConsoleKey.Q)
                            Flight = false;
                    }
                }
                Communicator.Stop();
            }

        }


        static void Program_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Console.WriteLine(((Exception)e.ExceptionObject).Message);
        }

    }
}